<template>
    <div class="canvasBox" ref="canvasBox">
        <div id="canvasbox"></div>
        <slot></slot>
    </div>
</template>
<script>
import G6 from '@antv/g6';
import {fittingString, stepCreateNodes} from './data';
export default {
    name:'G6Box',
    data(){
        return{
            originalData:null, // 接口返回全部数据
            graph:null, // graph实例
            graphData:null, // graph渲染数据
            defautlZoom:2.5,  // 原始缩放大小
            hasShowNums:0,
            pageSize:10,
            width:0,    // 画布宽
            height:0,   // 画布高
            isBindHandler:false, // 是否绑定事件
            isNodeSelected:false,  // 是否点击选中事件节点
            isEdgeSelected:false,   // 是否点击选中事件节点
            excludeWidth:0,     // 画布相对于屏幕宽需要排除的宽
            excludeHeight:0,     // 画布相对于屏幕高需要排除的高
            reasonTypeMap:null,    // 原因类型
            selectedNodeColor:null,
        }
    },
    props:{},
    created(){
        

    },
    mounted(){
        console.log('canvasBox',this.$refs.canvasBox.style.width)
    },
    beforeDestroy(){
        if(this.graph){
            this.graph.get('destroyed');
        }
    },
    methods:{
        // 初始化graph
        initGraph(list,excludeWidth,excludeHeight,reasonTypeMap){
            this.originalData = list;
            this.excludeWidth = excludeWidth;
            this.excludeHeight = excludeHeight;
            this.reasonTypeMap = reasonTypeMap;
            console.log('list',list)
            this.width = document.body.clientWidth - excludeWidth;
            this.height = document.body.clientHeight - excludeHeight;
            const vm = this;
            const grid = new G6.Grid();
            const menu = new G6.Menu({
                offsetX:   -20,
                offsetY:   -50,
                itemTypes: ['node', 'edge'],
                getContent(e) {
                    const outDiv = document.createElement('div');
                    outDiv.style.width = '80px';
                    outDiv.style.cursor = 'pointer';
                    outDiv.innerHTML = '<p id="deleteNode">删除节点</p>';
                    return outDiv;
                },
                handleMenuClick(target, item) {
                    const { id } = target;
                    if(id) {
                        vm[id](item);
                    }
                },
            });
            // const minimap = new G6.Minimap({
            //     size: [140, 60],
            // });
            const tooltip = new G6.Tooltip({
                offsetX: 10,
                offsetY: 0,
                // v4.2.1 起支持 fixToNode，tooltip 相对于节点固定位置
                fixToNode: [1, 0],
                // the types of items that allow the tooltip show up
                // 允许出现 tooltip 的 item 类型
                itemTypes: ['node', 'edge'],
                // custom the tooltip's content
                // 自定义 tooltip 内容
                getContent: (e) => {
                    // console.log('getContent',e.target);
                    const outDiv = document.createElement('div');
                    outDiv.style.width = 'fit-content';
                    outDiv.style.padding = '0px 0px 20px 0px';
                    outDiv.innerHTML = `
                    <p style="max-width:200px;">${e.target.attrs.abstract}</p>
                    `;
                    return outDiv;
                },
                shouldBegin:(e) => {
                    const target = e.target;
                    const targetName = target.get('name');
                    switch(targetName){
                        case 'containt-text':
                        case 'abstract-text':
                            return true;
                        default:
                            return false;
                    }
                }
            });
            this.graph = new G6.Graph({
                container: 'canvasbox', // String | HTMLElement，必须，在 Step 1 中创建的容器 id 或容器本身
                width: this.width, // Number，必须，图的宽度
                height: this.height, // Number，必须，图的高度
                // minZoom:2.5,
                // maxZoom:5,
                // 所有节点默认配置
                defaultNode: {
                    // style:{
                    //     cursor:'pointer'
                    // }
                },
                // 所有边的默认配置
                defaultEdge: {
                    type:  'line', // 扩展了内置边, 有边的事件
                    style: {
                        lineWidth: 1,
                        lineAppendWidth: 10, // 防止线太细没法点中
                    },
                },
                // 覆盖全局样式
                nodeStateStyles: {
                    'active': {
                        opacity: 1,
                        labelCfg:{
                            style:{
                                opacity:1,
                            }
                        }
                    },
                    'gray':{
                        opacity: 0.2,
                        labelCfg:{
                            style:{
                                opacity:0.2,
                            }
                        }
                    }
                },
                //默认边不同状态下的样式集合
                edgeStateStyles: {
                    'active': {
                        opacity:1,
                        labelCfg:{
                            style:{
                                opacity:1,
                            }
                        }
                    },
                    'gray': {
                        opacity:0.2,
                        labelCfg:{
                            style:{
                                opacity:0.2,
                            }
                        }
                    },
                },
                modes: {
                // 支持的 behavior
                    default:[
                        {
                            type:'drag-canvas',
                            // direction:'x'
                        }],
                },
                plugins: [menu,tooltip],
            });
            this.registerItem(); // 注册自定义节点和边
            this.graphData = this.stepCreateNode(list,reasonTypeMap); // 接口数据格式转换
            this.graph.data(this.graphData); // 加载数据
            this.graph.render(); // 渲染图
            let moveToX = this.width;
            let moveToY = this.height;
            this.graph.zoomTo(2.5,{x:moveToX,y:moveToY});
            this.bindEventHandler();
            this.canvasResize();
        },
        // 分步抽取data，进供模拟数据用
        stepCreateNode(_data,reasonTypeMap){
            let data = stepCreateNodes(this.width,this.height,this.hasShowNums,_data,reasonTypeMap);
            this.hasShowNums = _data.list.length;
            return data;
        },
        // 注册自定义元素
        registerItem(){
            // 自定义事件节点
            G6.registerNode('event-node',{
                draw(cfg,group){
                    const {
                        x,y,id,
                        containt,style,reasonType,
                        labelCfg,
                        abstract,
                        weight,
                        timeId
                    } = cfg;
                    const {width,height,fill} = style;
                    let padding = 2;
                    let stroke = reasonType[0].color
                    // eventNodesWithTimeMap.set()
                    // let abstractCfg = {
                    //     height:labelCfg.style.fontSize + padding * 2,
                    //     width:width,
                    //     // fill:'#C6E5FF',
                    //     stroke:'#5B8FF9',
                    //     labelCfg:{
                    //         style:{
                    //             stroke:'#5B8FF9',
                    //             fill:'#000'
                    //         }
                    //     }
                    // }
                    // let containtCfg = {
                    //     fill:'#C6E5FF',
                    //     stroke:'#5B8FF9',
                    //     labelCfg:{
                    //         style:{
                    //             stroke:'#5B8FF9',
                    //             fill:'#5B8FF9'
                    //         }
                    //     }
                    // }
                    const keyshape = group.addShape('rect',{
                        name:'event-node-box',
                        attrs:{
                            x:-width /2,
                            y:-height/2,
                            width: width + padding * 2,
                            height: height + padding * 2,
                            fill: '#fff',
                            // stroke: reasonType.color,
                            // stroke: '#ccc',
                            stroke,
                            lineWidth:0.5,
                            radius:2,
                            opacity:0.8,
                            cursor:'pointer'
                        }
                    });
                    group.addShape('text',{
                        name:'containt-text',
                        attrs:{
                            x: -width/2 + padding,
                            y: -height/2 + padding,
                            textAlign: "start",
                            textBaseline: "top",
                            text:fittingString(abstract,width - padding * 2,height - padding * 2,labelCfg.style.fontSize),
                            // fill:'#3A58B9',
                            fill:'#999399',
                            fontSize:labelCfg.style.fontSize,
                            _text:containt,
                            cursor:'pointer',
                            abstract
                        }
                    })
                    // const keyshape = group.addShape('rect',{
                    //     name:'event-node-box',
                    //     attrs:{
                    //         x:-width /2,
                    //         y:-height/2,
                    //         width: width + padding * 2,
                    //         height: height + abstractCfg.height + padding * 3,
                    //         // fill: fill,
                    //         stroke: reasonType.color,
                    //         lineWidth:0.5,
                    //         radius:2,
                    //         // opacity:0.8
                    //     }
                    // });
                    
                    // 顶部摘要框
                    // const abstractGroup = group.addGroup({
                    //     name:'abstract-group'
                    // })
                    // abstractGroup.addShape('rect',{
                    //     name:'abstract-box',
                    //     attrs:{
                    //         x:-width/2 + padding,
                    //         y:-height/2 + padding,
                    //         width: abstractCfg.width,
                    //         height:abstractCfg.height,
                    //         fill:abstractCfg.fill,
                    //         stroke:abstractCfg.stroke,
                    //         radius:2,
                    //         lineWidth:0.5,
                    //     }
                    // })
                    // abstractGroup.addShape('text',{
                    //     name:'abstract-text',
                    //     attrs:{
                    //         x: -width/2 + padding * 2,
                    //         y: -height/2 + padding * 2,
                    //         textAlign:"start",
                    //         textBaseline:"top",
                    //         // text:fittingStringByEllopsis(abstract,abstractCfg.width - padding * 2,labelCfg.style.fontSize),
                    //         text:weight,
                    //         fill:abstractCfg.labelCfg.style.fill,
                    //         fontSize:labelCfg.style.fontSize,
                    //         _text:abstract
                    //     }
                    // })
                    // let containtGroup = group.addGroup({
                    //     name:'containt-group'
                    // })
                    // containtGroup.addShape('rect',{
                    //     name:'containt-box',
                    //     attrs:{
                    //         x: -width/2 + padding,
                    //         y: -height/2 + abstractCfg.height + padding * 2,
                    //         width: width,
                    //         height:height,
                    //         fill:containtCfg.fill,
                    //         stroke:containtCfg.stroke,
                    //         lineWidth:0.5,
                    //         radius:2
                    //     }
                    // })
                    // containtGroup.addShape('text',{
                    //     name:'containt-text',
                    //     attrs:{
                    //         x: -width/2 + padding * 2,
                    //         y: -height/2 + padding * 3 + abstractCfg.height,
                    //         textAlign: "start",
                    //         textBaseline: "top",
                    //         text:fittingString(containt,width - padding * 4,height - padding * 4,labelCfg.style.fontSize),
                    //         fill:labelCfg.style.fill,
                    //         fontSize:labelCfg.style.fontSize,
                    //         _text:containt
                    //     }
                    // })
                    return keyshape;
                },
                // afterDraw:()=>{},
                setState:(name,value,item)=>{
                    const shape = item.get('keyShape');
                    const group = item.getContainer();
                    const text = group.get('children')[1];
                    const stroke = this.selectedNodeColor;
                    // console.log('stroke',stroke)
                    const model = item.getModel();
                    // console.log('model',model);
                    let defaultStroke = model.reasonType[0].color;
                    const nodeActiveStyle = {
                        opacity:1,
                        lineWidth:1,
                        stroke:stroke ? stroke : defaultStroke
                    };
                    const textActiveStyle = {
                        opacity:1,
                        lineWidth:0.5
                    }
                    const nodeDefaultStyle = {
                        opacity:1,
                        lineWidth:0.5,
                        stroke:defaultStroke
                    };
                    const textDefaultStyle = {
                        opacity:1,
                        lineWidth:0.5
                    }
                    const nodeGrayStyle = {
                        opacity:0.2,
                        lineWidth:0.5,
                        stroke:'#ccc'
                    };
                    const textGrayStyle = {
                        opacity:0.2,
                        lineWidth:0.5
                    }
                    if(name === 'active'){
                        console.log('active')
                        if(value){
                            shape.attr(nodeActiveStyle);
                            text.attr(textActiveStyle);
                        }else{
                            shape.attr(nodeDefaultStyle);
                            text.attr(textDefaultStyle);
                        }
                    }else if(name === 'gray'){
                        console.log('gray')
                        if(value){
                            shape.attr(nodeGrayStyle);
                            text.attr(textGrayStyle);
                        }else{
                            shape.attr(nodeDefaultStyle);
                            text.attr(textDefaultStyle);
                        }
                    }
                }
            });
            // 自定义时间节点
            G6.registerNode('time-node',{
                draw(cfg,group){
                    let {
                        r,
                        labelCfg,
                        label
                    } = cfg;
                    const keyShape = group.addShape('circle',{
                        name:'time-circle',
                        attrs:{
                            x:r,
                            y:r,
                            stroke:'#bbb',
                            r
                        }
                    })
                    group.addShape('text',{
                        name:'time-text',
                        attrs:{
                            x: 0,
                            y: labelCfg.offset,
                            textAlign: "center",
                            textBaseline: "top",
                            text:label,
                            lineWidth:0.5,
                            fill:"#bbb",
                            fontSize:labelCfg.style.fontSize
                        }
                    })
                    return keyShape
                },
                setState(name,value,item){
                    const shape = item.get('keyShape');
                    const group = item.getContainer();
                    const text = group.get('children')[1];
                    const model = item.getModel();
                    const nodeActiveStyle = {
                        opacity:1,
                        lineWidth:1,
                        // stroke:  model.stroke
                    };
                    const nodeDefaultStyle = {
                        opacity:1,
                        lineWidth:0.5
                    };
                    const nodeGrayStyle = {
                        opacity:0.2,
                        lineWidth:0.5
                    };
                    const textActiveStyle = { opacity:1};
                    const textDefaultStyle = {opacity:1};
                    const textGrayStyle = {opacity:0.2};
                    if(name === 'active'){
                        if(value){
                            shape.attr(nodeActiveStyle);
                            text.attr(textActiveStyle);
                        }else{
                            shape.attr(nodeDefaultStyle);
                            text.attr(textDefaultStyle);
                        }
                    }else if(name === 'gray'){
                        if(value){
                            shape.attr(nodeGrayStyle);
                            text.attr(textGrayStyle);
                        }else{
                            shape.attr(nodeDefaultStyle);
                            text.attr(textDefaultStyle);
                        }
                    }

                }
            });
            // 自定义关系连线
            G6.registerEdge('event-arrow',{
                draw(cfg,group){
                    let {
                        sourceColumn,
                        targetColumn,
                        sourceRow,
                        targetRow,
                        sourceWeight,
                        targetWeight,
                        offset,
                        eventNodeHeight,
                        step,
                        isTowWay,
                        relationship,
                        reverseRelationship
                    } = cfg;
                    // let stroke = relationship ? relationship.color : reverseRelationship ? reverseRelationship.color : '#ccc';
                    let stroke = '#ccc';
                    
                    const startPoint = cfg.startPoint;
                    const endPoint = cfg.endPoint;
                    let path = [];
                    if((sourceColumn === targetColumn || sourceRow === targetRow) && Math.abs(sourceWeight - targetWeight) === 1){ // 指相邻的两个事件间连线
                        path = [
                            ['M', startPoint.x, startPoint.y],
                            ['L', endPoint.x, endPoint.y]
                        ]
                    }else if((sourceColumn === targetColumn && Math.abs(sourceWeight - targetWeight) > 1) || Math.abs(sourceColumn - targetColumn) === 1){
                        // 列数相同但不相邻
                        console.log('列数相同但不相邻')
                        path = [
                            ['M', startPoint.x, startPoint.y],
                            ['L', startPoint.x + offset, startPoint.y],
                            ['L', startPoint.x + offset, endPoint.y],
                            ['L', endPoint.x, endPoint.y],
                        ]
                    } else if(sourceRow === targetRow && Math.abs(sourceWeight - targetWeight) > 1){
                        // 行数相同但不相邻
                        path = [
                            ['M', startPoint.x, startPoint.y],
                            ['L', startPoint.x, startPoint.y + offset],
                            ['L', endPoint.x, startPoint.y + offset,],
                            ['L', endPoint.x, endPoint.y]
                        ]
                    }else{
                        //'行列都不相同'
                        let l0_x = startPoint.x;
                        let l0_y = startPoint.y;
                        let l1_x = sourceColumn > targetColumn ? startPoint.x + offset : startPoint.x - offset;
                        let l1_y = startPoint.y;
                        let l2_x = l1_x;
                        let l2_y = targetRow > sourceRow ? startPoint.y - (eventNodeHeight / 2 + offset) : startPoint.y + (eventNodeHeight / 2 + offset);
                        let l3_x = sourceColumn > targetColumn ? l2_x + step * (sourceColumn - targetColumn - 1) :
                        l2_x - step * (targetColumn - sourceColumn - 1);
                        let l3_y = l2_y;
                        let l4_x = l3_x;
                        let l4_y = endPoint.y;
                        let l5_x = endPoint.x;
                        let l5_y = endPoint.y;
                        path = [
                            ['M',l0_x,l0_y],
                            ['L',l1_x,l1_y],
                            ['L',l2_x,l2_y],
                            ['L',l3_x,l3_y],
                            ['L',l4_x,l4_y],
                            ['L',l5_x,l5_y],
                        ]
                    }
                    const keyshape = group.addShape('path',{
                        name:'arrow-edge',
                        attrs:{
                            defaultStroke:stroke,
                            lineWidth:0.5,
                            path:path,
                            stroke,
                            endArrow:{ path:G6.Arrow.triangle(2,4,0) },
                            startArrow: isTowWay ? { path:G6.Arrow.triangle(2,4,0) } : false,
                            opacity:0.5,
                            lineAppendWidth:10,
                            cursor:'pointer'
                        }
                    })
                    return keyshape;
                },
                afterDraw(cfg,group){
                    let {
                        sourceColumn,
                        targetColumn,
                        sourceRow,
                        targetRow,
                        isTowWay,
                        relationship,
                        reverseRelationship,
                        fontSize
                    } = cfg;
                    let fill = '#ccc';
                    const shape = group.get('children')[0];
                    const midPoint = shape.getPoint(0.5);
                    let textPointX_forward = midPoint.x;
                    let textPointY_forward = midPoint.y - fontSize;
                    let textPointX_reverse = midPoint.x;
                    let textPointY_reverse = midPoint.y + fontSize;
                    if((Math.abs(sourceColumn - targetColumn) <= 1 && sourceRow !== targetRow )|| (Math.abs(sourceColumn - targetColumn) === 2 && Math.abs(sourceRow - targetRow) === 2)){
                        textPointX_forward = midPoint.x - fontSize * 1.5;
                        textPointY_forward = midPoint.y;
                        textPointX_reverse = midPoint.x + fontSize * 1.5;
                        textPointY_reverse = midPoint.y;
                    }
                    if(relationship){
                        group.addShape('text',{
                            name:'arrow-top-text',
                            attrs:{
                                x:textPointX_forward,
                                y:textPointY_forward,
                                textAlign: "center",
                                textBaseline: "middle",
                                text:relationship.value,
                                // fill:relationship.color,
                                fill,
                                opacity:0.5,
                                fontSize,
                                cursor:'pointer'
                            }
                        })
                    }
                    if(reverseRelationship){
                        group.addShape('text',{
                            name:'arrow-bottom-text',
                            attrs:{
                                x:textPointX_reverse,
                                y:textPointY_reverse,
                                textAlign: "center",
                                textBaseline: "middle",
                                text:reverseRelationship.value,
                                // fill:reverseRelationship.color,
                                fill,
                                opacity:0.5,
                                fontSize,
                                cursor:'pointer'
                            }
                        })
                    }
                },
                setState(name,value,item){
                    const shape = item.get('keyShape');
                    const group = item.getContainer();
                    const topText = group.get('children')[1];
                    const bottomText = group.get('children')[2];
                    const edgeActiveStyle = {
                        opacity:1,
                        lineWidth:1
                    };
                    const edgeDefaultStyle = {
                        opacity:1,
                        lineWidth:0.5
                    };
                    const edgeGrayStyle = {
                        opacity:0.2,
                        lineWidth:0.5
                    };
                    const textActiveStyle = { opacity:1};
                    const textDefaultStyle = {opacity:0.5};
                    const textGrayStyle = {opacity:0.2};

                    if(name === 'active'){
                        if(value){
                            shape.attr(edgeActiveStyle);
                            topText && topText.attr(textActiveStyle);
                            bottomText && bottomText.attr(textActiveStyle);
                        }else{
                            shape.attr(edgeDefaultStyle);
                            topText && topText.attr(textDefaultStyle);
                            bottomText && bottomText.attr(textDefaultStyle);
                        }
                    }else if(name === 'gray'){
                        if(value){
                            shape.attr(edgeGrayStyle);
                            topText && topText.attr(textGrayStyle);
                            bottomText && bottomText.attr(textGrayStyle);
                        }else{
                            shape.attr(edgeDefaultStyle);
                            topText && topText.attr(textDefaultStyle);
                            bottomText && bottomText.attr(textDefaultStyle);
                        }
                    }
                },
                // updata:undefined
            });
        },
        // 清除所有节点和边的样式到初始样式
        clearAllState(){
            this.graph.setAutoPaint(false);
            this.graph.getNodes().forEach((node)=>{
                this.graph.clearItemStates(node);
            });
            this.graph.getEdges().forEach((edge)=>{
                this.graph.clearItemStates(edge);
            });
            this.graph.paint();
            this.graph.setAutoPaint(true);
        },
        // 绑定事件
        bindEventHandler(){
            this.isBindHandler = true;
            this.graph.on('node:click',(ev)=>{
                console.log(ev.item)
                this.graph.setAutoPaint(false);
                if(!this.isNodeSelected){
                    const node = ev.item;
                    const model = node.getModel(); // 节点原始数据
                    const nodeType = model.type;   // 节点类型
                    if(nodeType === 'event-node'){
                        const timeNodeId = model.timeId;
                        const relationTimeId = new Set([timeNodeId]);
                        // 先将所有节点置灰
                        this.graph.getNodes().forEach(node=>{
                            this.graph.clearItemStates(node);
                            this.graph.setItemState(node,'gray',true)
                        })
                        this.graph.getEdges().forEach(edge=>{
                            let model = edge.getModel();
                            if(model.edgeType === 'horizontal-timeline')return;
                            this.graph.clearItemStates(edge);
                            this.graph.setItemState(edge,'gray',true)
                        })
                        // 当前事件节点高亮
                        this.graph.setItemState(node,'gray',false);
                        this.graph.setItemState(node,'active',true);
                        console.log('node active')
                        const neighborsNodes = node.getNeighbors();
                        const neighborsEdges = node.getEdges();
                        // 当前事件相关的其他事件节点高亮
                        neighborsNodes.forEach(neiNode=>{
                            let neiNodeTimeId = neiNode.getModel().timeId;
                            this.graph.setItemState(neiNode,'gray',false);
                            this.graph.setItemState(neiNode,'active',true);
                            console.log('neiNode active')
                            if(neiNodeTimeId && !relationTimeId.has(neiNodeTimeId)){
                                relationTimeId.add(neiNodeTimeId)
                            }
                            
                        })
                        // 当前事件相关的关系高亮
                        neighborsEdges.forEach(neiEdge=>{
                            let neiEdgeType = neiEdge.getModel().type;
                            if(neiEdgeType !== 'line'){ // 排除时间和事件间的竖向连线的高亮
                                this.graph.setItemState(neiEdge,'gray',false);
                                this.graph.setItemState(neiEdge,'active',true);
                            }
                        })
                        // 当前事件对应的时间节点高亮
                        relationTimeId.forEach(timeNodeId=>{
                            let timeNode = this.graph.findById(timeNodeId);
                            this.graph.clearItemStates(timeNode);
                            this.graph.setItemState(timeNode,'active',true);
                        })
                    }else if(nodeType === 'time-node'){

                    }
                }else{
                    this.clearAllState();
                }
                this.isNodeSelected = !this.isNodeSelected;
                this.graph.paint();
                this.graph.setAutoPaint(true);
            })
            this.graph.on('edge:click',(ev)=>{
                this.graph.setAutoPaint(false);
                if(!this.isEdgeSelected){
                    const edge = ev.item;
                    const model = edge.getModel();
                    const edgeType = model.type;
                    if(edgeType === 'event-arrow'){
                        this.graph.getNodes().forEach(node=>{
                            this.graph.clearItemStates(node);
                            this.graph.setItemState(node,'gray',true);
                        })
                        this.graph.getEdges().forEach(edge=>{
                            let model = edge.getModel();
                            if(model.edgeType === 'horizontal-timeline')return;
                            this.graph.clearItemStates(edge);
                            this.graph.setItemState(edge,'gray',true);
                        })
                        this.graph.setItemState(edge,'gray',false);
                        this.graph.setItemState(edge,'active',true);
                        const source = edge.getSource();
                        const target = edge.getTarget();
                        this.graph.setItemState(source,'gray',false);
                        this.graph.setItemState(target,'gray',false);
                        this.graph.setItemState(source,'active',true);
                        this.graph.setItemState(target,'active',true);
                        let sourceTimeNodeId = source.getModel().timeId;
                        let targetTimeNodeId = target.getModel().timeId;
                        let sourceTimeNode = this.graph.findById(sourceTimeNodeId);
                        let targetTimeNode = this.graph.findById(targetTimeNodeId);
                        this.graph.setItemState(sourceTimeNode,'gray',false);
                        this.graph.setItemState(targetTimeNode,'gray',false);
                        this.graph.setItemState(sourceTimeNode,'active',true);
                        this.graph.setItemState(targetTimeNode,'active',true);
                    }else{

                    }
                }else{
                    this.clearAllState();
                }
                this.isEdgeSelected = !this.isEdgeSelected;
                this.graph.paint();
                this.graph.setAutoPaint(true);
            })
            this.graph.on('canvas:click',()=>{
                if(this.isNodeSelected || this.isEdgeSelected){
                    if(this.isEdgeSelected){
                        this.isEdgeSelected = false;
                    }
                    if(this.isNodeSelected){
                        this.isNodeSelected = false;
                    }
                    this.graph.setAutoPaint(false);
                    this.clearAllState();
                    this.graph.paint();
                    this.graph.setAutoPaint(true);
                }
            })
        },
        removeEventHandler(){
            this.isBindHandler = false;
            this.graph.off('node:click');
            this.graph.off('edge:click');
            this.graph.off('canvas:click');
        },
        selectReason({data,selectedNodeColor} = {}){
            if(!data){ // 选择全部
                this.selectedNodeColor = null;
                this.graph.getNodes().forEach(node=>{
                    this.graph.clearItemStates(node);
                })
                this.graph.getEdges().forEach(edge=>{
                    this.graph.clearItemStates(edge);
                })
                // 绑定所有事件监听
                if(!this.isBindHandler){
                    this.bindEventHandler();
                }
                return;
            }
            console.log('reasonTypeMap',this.reasonTypeMap)
            
            this.selectedNodeColor = selectedNodeColor;
            console.log('selectReason selectedNodeColor',this.selectedNodeColor)
            // 解除所有事件绑定
            if(this.isBindHandler){
                this.removeEventHandler();
            }
            this.graph.setAutoPaint(false);
            // 选中节点id列表
            let nodeIds = data.nodes;
            // 选中所有边ID列表
            let edgeIds = data.edges.map(edgeOriginData=>`${edgeOriginData.sourceId}-${edgeOriginData.targetId}`)
            let relationTimeId = new Set();
            // 先将所有节点置灰
            this.graph.getNodes().forEach(node=>{
                this.graph.clearItemStates(node);
                this.graph.setItemState(node,'gray',true);
            })
            this.graph.getEdges().forEach(edge=>{
                let model = edge.getModel();
                if(model.edgeType === 'horizontal-timeline')return;
                this.graph.clearItemStates(edge);
                this.graph.setItemState(edge,'gray',true)
            })
            nodeIds.forEach(nodeId=>{
                let selectedNode = this.graph.findById(nodeId);
                let timeId = selectedNode.getModel().timeId;
                this.graph.setItemState(selectedNode,'gray',false);
                this.graph.setItemState(selectedNode,'active',true);
                if( timeId && !relationTimeId.has(timeId)){
                    relationTimeId.add(timeId)
                }
            })
            edgeIds.forEach(edgeId=>{
                let selectedEdge = this.graph.findById(edgeId);
                this.graph.setItemState(selectedEdge,'gray',false);
                this.graph.setItemState(selectedEdge,'active',true);
            })
            // 事件对应的时间节点高亮
            relationTimeId.forEach(timeNodeId=>{
                let timeNode = this.graph.findById(timeNodeId);
                this.graph.clearItemStates(timeNode);
                this.graph.setItemState(timeNode,'active',true);
            })
            this.graph.paint();
            this.graph.setAutoPaint(true);
        },
        // 监听resize事件重置画布大小
        canvasResize(){
            window.addEventListener('resize',()=>{
                if (!this.graph || this.graph.get('destroyed')) return;
                // console.log('before:width,height',this.width,this.height);
                const ratio = (document.body.clientHeight - this.excludeHeight) / this.height;
                const zoom = this.defautlZoom * ratio;
                
                this.width = document.body.clientWidth - this.excludeWidth;
                this.height = document.body.clientHeight - this.excludeHeight;
                // console.log('after:width,height',this.width,this.height);
                this.graph.changeSize(this.width,this.height);
                this.graph.zoom(ratio)
            })
        }
    },
    watch:{}
}
</script>
<style lang="scss">
/* 提示框的样式 */
  .g6-tooltip {
    position: fixed;
    top: 0;
    left: 0;
    font-size: 12px;
    color: #545454;
    border-radius: 4px;
    border: 1px solid #e2e2e2;
    background-color: rgba(255, 255, 255, 0.9);
    box-shadow: rgb(174, 174, 174) 0 0 10px;
    padding: 10px 8px;
  }
  .g6-minimap{
    position: absolute;
    right: 0;
    bottom: 0;
    background:#fff;
  }
  .g6-minimap-container {
    border: 1px solid #e2e2e2;
  }
  .g6-minimap-viewport {
    border: 1px solid rgb(25, 128, 255);
    // height:100%!important;
    // width:20px!important;
  }
</style>